package com.one.rope.mvp.web.controller.third;

import com.one.rope.mvp.basecore.bean.ResponseObject;
import com.one.rope.mvp.basecore.third.wx.WxSignUtil;
import com.one.rope.mvp.basecore.third.wx.common.WxGetUserInfoRes;
import com.one.rope.mvp.basecore.third.wx.common.WxPushMsgReq;
import com.one.rope.mvp.basecore.third.wx.common.WxSendCustomTextMsgReq;
import com.one.rope.mvp.basecore.third.wx.common.WxSendMsgRes;
import com.one.rope.mvp.basecore.util.JsonUtils;
import com.one.rope.mvp.basecore.util.StringUtils;
import com.one.rope.mvp.basecore.util.XMLUtil;
import com.one.rope.mvp.web.business.entity.MemberSubscribeRecord;
import com.one.rope.mvp.web.common.dto.common.wx.GenerateQrcodeVO;
import com.one.rope.mvp.web.config.CommonConfig;
import com.one.rope.mvp.web.config.GlobalConfig;
import com.one.rope.mvp.web.service.user.WxOfficialService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 *
 *                    _ooOoo_
 *                   o8888888o
 *                   88" . "88
 *                   (| -_- |)
 *                   O\  =  /O
 *                ____/`---'\____
 *              .'  \\|     |//  `.
 *             /  \\|||  :  |||//  \
 *            /  _||||| -:- |||||-  \
 *            |   | \\\  -  /// |   |
 *            | \_|  ''\---/''  |   |
 *            \  .-\__  `-`  ___/-. /
 *          ___`. .'  /--.--\  `. . __
 *       ."" '<  `.___\_<|>_/___.'  >'"".
 *      | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *      \  \ `-.   \_ __\ /__ _/   .-` /  /
 * ======`-.____`-.___\_____/___.-`____.-'======
 *                    `=---='
 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *             佛祖保佑       永无BUG
 *
 * <p>
 * 微信开放平台相关控制器
 * <p>
 *
 * @author ： Weijian.Liu
 * @date ： 2020/3/27 17:29
 */
@Api(tags = "C2微信开放平台相关")
@RestController
@RequestMapping("/third/wx-api")
@Slf4j
public class WxOpenController {

  @Autowired
  CommonConfig commonConfig;

  @Autowired
  WxOfficialService wxOfficialService;

  @ApiOperation(value = "THIRD001 验证微信服务器", notes = "验证微信服务器接口")
  @GetMapping(value = "/checkSignature")
  public void checkSignature(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) {
    if (!StringUtils.isNullOrEmpty(echostr)) {
      String signatureRet = WxSignUtil.getSignature(commonConfig.getWxServerToken(), timestamp, nonce);
      signatureRet = signatureRet.toLowerCase();
      try {
        if (!StringUtils.isNullOrEmpty(signatureRet) && signatureRet.equals(signature)) {
          response.getWriter().println(echostr);
        }else{
          log.error("微信服务器验证失败");
        }
      }catch (Exception e){
        log.error("微信服务器验证失败", e);
      }
    }
  }

  @ApiOperation(value = "THIRD002 接收微信公众号推送消息事件", notes = "用于接收扫码后关注公众号，微信服务器将xml数据推送给此接口，接收xml数据后推送小程序")
  @PostMapping(value = "/checkSignature")
  public void receivePushMessage(HttpServletRequest request, HttpServletResponse response){
    log.info("进入微信公众号推送消息事件>>>>");
    try {
      ServletInputStream in = request.getInputStream();
      BufferedReader reader = new BufferedReader(new InputStreamReader(in));
      String requestDataXml = "";
      String itemStr= ""; //作为输出字符串的临时串，用于判断是否读取完毕
      while( null != (itemStr = reader.readLine())){
        requestDataXml += itemStr;
      }
      log.info("收到消息XML内容: {}", requestDataXml);
      Map<String, String> reqMap = XMLUtil.doXMLParse(requestDataXml);
      String reqJson = JsonUtils.mapToJsonString(reqMap);
      log.info("收到消息JSON内容: {}", reqJson);
      WxPushMsgReq msgDTO = (WxPushMsgReq)JsonUtils.stringToObject(reqJson, WxPushMsgReq.class);
      if (msgDTO.getMsgType().equals("event")) {
        if("subscribe".equals(msgDTO.getEvent())){
          if(StringUtils.isNullOrEmpty(msgDTO.getEventKey())){
            log.info("***普通关注***");
            return;
          }else{
            log.info("带参数二维码关注，接收消息EventKey： {}", msgDTO.getEventKey());
            WxSendCustomTextMsgReq msgReq = new WxSendCustomTextMsgReq();
            msgReq.setToUser(msgDTO.getFromUserName());
            if(("qrscene_"+GlobalConfig.QRCODE_TO_B_SCENE_STR).equals(msgDTO.getEventKey())){
              // 扫B端二维码关注
              msgReq.setContent(GlobalConfig.B_MSG_DOC+"<a href=\"http://www.duozhu.co\" data-miniprogram-appid=\""+commonConfig.getWxMiniProgramSkipAppId()+"\" "
                  + "data-miniprogram-path=\""+commonConfig.getWxMiniProgramSkipBIndexPath()+"\">"+GlobalConfig.SKIP_B_TITLE+"</a>");
            }else if(("qrscene_"+GlobalConfig.QRCODE_TO_C_SCENE_STR).equals(msgDTO.getEventKey())){
              // 扫C端二维码关注
              msgReq.setContent(GlobalConfig.C_MSG_DOC+"<a href=\"http://www.duozhu.co\" data-miniprogram-appid=\""+commonConfig.getWxMiniProgramSkipAppId()+"\" "
                  + "data-miniprogram-path=\""+commonConfig.getWxMiniProgramSkipCIndexPath()+"\">"+GlobalConfig.SKIP_C_TITLE+"</a>");
            }
            WxSendMsgRes sendMsgRes = wxOfficialService.sendCustomerTextMsg(msgReq);
            log.info("*************推送小程序结束, result:{}", sendMsgRes);

            // 保存关注记录
            WxGetUserInfoRes userInfoRes = wxOfficialService.getUserInfo(msgDTO.getFromUserName());
            if(StringUtils.isNullOrEmpty(userInfoRes.getErrmsg())){
              MemberSubscribeRecord subscribeRecord = new MemberSubscribeRecord();
              subscribeRecord.setOfficicalId(msgDTO.getToUserName());
              subscribeRecord.setWxOfficialOpenId(msgDTO.getFromUserName());
              subscribeRecord.setWxUnionId(userInfoRes.getUnionid());
              wxOfficialService.saveMemberSubscribeRecord(subscribeRecord);
            }else{
              log.error("获取公众号用户基本信息失败，原因:[{}]", userInfoRes.getErrmsg());
            }

          }
        }else if("unsubscribe".equals(msgDTO.getEvent())){
          // 取消关注
          log.info("***取消关注***");
        }else if("TEMPLATESENDJOBFINISH".equals(msgDTO.getEvent())){
          // 事件推送
          // 在模版消息发送任务完成后，微信服务器会将是否送达成功作为通知，发送到开发者中心中填写的服务器配置地址中
          log.info("***模板消息发送完成***");
        }
      }

    }catch (Exception e){
      log.error("接收微信公众号推送消息失败: ", e);
    }
  }

  @ApiOperation(value = "THIRD003 生成带参数公众号二维码URL", notes = "生成带参数公众号二维码URL接口，供给用户扫码进入小程序使用")
  @GetMapping("/generateQrcode")
  public ResponseObject<GenerateQrcodeVO> generateQrcode(
      @ApiParam(name = "sceneStr", value = "二维码场景id，标识二维码类型.B端用户使用: USER_TO_B_PROGRAME，"
          + "C端使用: USER_TO_C_PROGRAME") @RequestParam("sceneStr") String sceneStr) {
    try {
      return wxOfficialService.generateQrcode(sceneStr);
    } catch (Exception e) {
      log.error("/common/generateQrcode接口异常", e);
      return ResponseObject.systemError(e);
    }
  }

}
